

// #pragma once
#ifndef _THREAD_H_
#define _THREAD_H_


#include <condition_variable>
#include <functional>
#include <mutex>
#include <pthread.h>

namespace zepco {

class Semaphore {
  public:

    // count = 0 表示初始为同步操作，只能调用singal
    explicit Semaphore(int count = 0) : m_count(count) {}

    // P
    void wait() {
        std::unique_lock<std::mutex> lock(m_mtx);
        while (m_count == 0) { // 防止虚假唤醒
            m_cond.wait(lock);
        }
        m_count --;
    }

    // V
    void singal() {
        std::unique_lock<std::mutex> lock(m_mtx);
        m_count ++;
        m_cond.notify_one();
    }

  private:
    std::mutex m_mtx;
    std::condition_variable m_cond;
    int m_count;
};

/**
 * @brief 补足协程无法使用多核资源的缺点
 *        使用多线程配合多协程是用多核资源
 * 
 */
class Thread {
  public:
    Thread(std::function<void()> callback, const std::string &name);
    ~Thread();
    pid_t getID() {
        return m_id;
    }
    const std::string &getName() {
        return m_name;
    }
    void join();
  public:

    static pid_t GetThreadID();
    static Thread *GetThis();
    static const std::string &GetThreadName();
    static void SetName(std::string &name);

  private:
    static void *run(void *arg);


  private:
    pid_t m_id;
    pthread_t m_thread;
    std::function<void()> m_callback;
    std::string m_name;
    Semaphore m_semaphore;
};

}
#endif // _THREAD_H_